﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace Tools.Utils
{
    public static class EnumHelper
    {
        /// <summary>
        /// 获取描述信息
        /// </summary>
        /// <param name="en"></param>
        /// <returns></returns>
        public static string GetDescription(Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            return en.ToString();
        }

        /// <summary>
        /// 获取枚举信息[item1:描述，item2:字符串值，item3:数字值，item4:枚举值
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static List<Tuple<string, string, int, T>> GetTuple<T>(Type enumType)
        {
            string[] nameList = Enum.GetNames(enumType);
            Array valueList = Enum.GetValues(enumType);
            List<Tuple<string, string, int, T>> data = new List<Tuple<string, string, int, T>>();
            for (int i = 0; i < nameList.Length; i++)
            {
                var obj = Enum.Parse(enumType, nameList[i]);
                var @enum = (Enum)obj;
                // 描述
                string typeName = GetDescription(@enum);
                string typeString = Enum.Parse(enumType, nameList[i]).ToString();
                // 值
                int typeValue = (int)((IList)valueList)[i];
                data.Add(Tuple.Create(typeName, typeString, typeValue, (T)obj));
            }
            return data;
        }

        /// <summary>
        /// 将字符串转换为枚举类型
        /// </summary>
        /// <typeparam name="T">转换后的枚举</typeparam>
        /// <param name="value">需要转换的值</param>
        /// <returns></returns>
        public static T ToEnum<T>(string value)
        {
            return (T)(Enum.Parse(typeof(T), value));
        }

        /// <summary>
        /// 将整形转换为枚举类型
        /// </summary>
        /// <typeparam name="T">转换后的枚举</typeparam>
        /// <param name="value">需要转换的值</param>
        /// <returns></returns>
        public static T ToEnum<T>(int value)
        {
            return ToEnum<T>(value.ToString());
        }

        /// <summary>
        /// 获得枚举的Description 转换为
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static float GetFloat(Enum value)
        {
            if (float.TryParse(GetDescription(value) ?? "", out float floatValue))
            {
                return floatValue;
            }
            return 0;
        }

        /// <summary>
        /// 根据描述获取枚举
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="description"></param>
        /// <returns></returns>
        public static T GetEnumByDescription<T>(string description)
        {
            Type _type = typeof(T);
            foreach (FieldInfo field in _type.GetFields())
            {
                DescriptionAttribute[] _curDesc = field.GetDescriptAttr();
                if (_curDesc != null && _curDesc.Length > 0)
                {
                    if (_curDesc[0].Description == description)
                        return (T)field.GetValue(null);
                }
                else
                {
                    if (field.Name == description)
                        return (T)field.GetValue(null);
                }
            }
            throw new ArgumentException(string.Format("{0} 未能找到对应的枚举.", description), "Description");
        }

        private static DescriptionAttribute[] GetDescriptAttr(this FieldInfo fieldInfo)
        {
            if (fieldInfo != null)
            {
                return (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            }
            return null;
        }

        /// <summary>
        /// 将枚举值通过描述信息转换为另一个枚举类型
        /// </summary>
        /// <typeparam name="T">转换后的枚举</typeparam>
        /// <param name="value">需要转换的值</param>
        /// <returns></returns>
        public static T ToEnum<T>(Enum value)
        {
            return GetEnumByDescription<T>(GetDescription(value));
        }

        /// <summary>
        /// 将可空整形转换为枚举类型
        /// </summary>
        /// <typeparam name="T">转换后的枚举</typeparam>
        /// <param name="value">需要转换的值</param>
        /// <returns></returns>
        public static T IsCanNullIntToEnum<T>(int? value)
        {
            return ToEnum<T>(value.HasValue.ToString());
        }
    }
}
